package com.gugee.ins.data.analysis.service.impl;

import com.gugee.common.thread.ScheduleTemplate;
import com.gugee.ins.common.dal.ai.AiAnalysisClient;
import com.gugee.ins.common.dal.service.blogger.InsBloggerDao;
import com.gugee.ins.common.dal.service.blogger.InsBloggerMainDao;
import com.gugee.ins.common.dal.service.media.InsMediaDao;
import com.gugee.ins.common.dal.service.media.InsRelMediaCaptionTagDao;
import com.gugee.ins.common.model.ai.InsBloggerCategory;
import com.gugee.ins.common.model.ai.InsBloggerCategoryResponse;
import com.gugee.ins.common.model.ai.InsBloggerMediaTag;
import com.gugee.ins.common.model.mysql.media.InsRelMediaCaptionTag;
import com.gugee.ins.data.analysis.config.InsAnalysisConfig;
import com.gugee.ins.data.analysis.service.InsAnalysisCategoryService;
import com.gugee.ins.data.common.msg.InsBloggerMessage;
import com.xiguaji.boot.toolkit.ThreadPoolUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ForkJoinPool;

/**
 * insBloggerLocation 服务
 * @author Huangxin
 */
@Slf4j
@Service
public class InsAnalysisCategoryServiceImpl implements InsAnalysisCategoryService {

    /**
     * 配置
     */
    @Autowired
    InsAnalysisConfig insAnalysisConfig;

    /**
     * 线程调度
     */
    @Autowired
    ScheduleTemplate scheduleTemplate;

    /**
     * ai
     */
    @Autowired
    AiAnalysisClient aiAnalysisClient;

    /**
     * InsBloggerDao
     */
    @Autowired
    InsBloggerDao insBloggerDao;

    /**
     * InsBloggerDao
     */
    @Autowired
    InsBloggerMainDao insBloggerMainDao;

    /**
     * InsMediaDao
     */
    @Autowired
    InsMediaDao insMediaDao;

    /**
     * insRelMediaCaptionTagDao
     */
    @Autowired
    InsRelMediaCaptionTagDao insRelMediaCaptionTagDao;

    /**
     * 线程池
     */
    ForkJoinPool forkJoinPool;

    /**
     * 线程名
     */
    private String workName = "insAnalysisCategory-worker";

    /**
     * 初始化线程池
     */
    @PostConstruct
    public void init() {
        forkJoinPool = ThreadPoolUtils.forkJoinPool(insAnalysisConfig.getInsAnalysisCategoryCorePollSize(), workName);
        scheduleTemplate.attach(workName, forkJoinPool);
    }

    /**
     * 处理 分析播主分类 任务
     * @param insBloggerMessages
     */
    @Override
    public void handleAnalysisCategory(List<InsBloggerMessage> insBloggerMessages) {
        try {
            if(!insBloggerMessages.isEmpty()){
                List<Long> uids = insBloggerMainDao.findEmptyCategoryByUid(insBloggerMessages);
                if(uids != null && !uids.isEmpty()){
                    forkJoinPool.submit(() -> uids.parallelStream().forEach(uid -> {
                        try {
                            // 分析语言
                            analysisCategory(uid);
                        } catch (Exception ex) {
                            log.error("insAnalysisCategory error. uid:{}, error :{}" ,
                                    uid,ex.getMessage());
                        }
                    })).get();
                }
            }
        } catch (Exception ex) {
            log.error("insAnalysisCategory thread error.  {}" ,  ex.getMessage());
        }
    }

    /**
     * 分析播主分类
     *
     * @param uid
     */
    public void analysisCategory(long uid){
        long start = System.currentTimeMillis();

        // 获取帖子标题
        List<InsRelMediaCaptionTag> captionsTags = insRelMediaCaptionTagDao.findCaptionTagByUid(uid);
        if(captionsTags != null && !captionsTags.isEmpty()){
            List<InsBloggerMediaTag> response = new ArrayList<>(1);
            InsBloggerMediaTag insBloggerMediaTag = new InsBloggerMediaTag();
            insBloggerMediaTag.setId(uid);
            insBloggerMediaTag.setTags(getMediaTag(captionsTags));
            response.add(insBloggerMediaTag);
            try {
                // 调用ai接口
                InsBloggerCategoryResponse result = aiAnalysisClient.getCategoryByText(response);
                if(result != null && result.getResult() != null && !result.getResult().isEmpty()){
                    List<InsBloggerCategory> insBloggerCategories = result.getResult();
                    updateCategory(insBloggerCategories);
                }
            }catch (Exception e){
                log.error("insAnalysisCategory get media caption ai result error, msg:{}",e.getMessage());
            }
        } else {
            // 记录一下最近分析时间代表最近查找过，定时任务不用频繁触发
            insBloggerMainDao.updateLastAnalysisCategoryTime(uid);
        }

        if ((System.currentTimeMillis() - start) / 1000 > insAnalysisConfig.getInsAnalysisCategoryDebugTimeLimit()) {
            log.info("insAnalysisCategory uid:{} use time:{}s", uid,(System.currentTimeMillis() - start) / 1000);
        }
    }

    /**
     * 更新分类
     * @param insBloggerCategories
     */
    public void updateCategory(List<InsBloggerCategory> insBloggerCategories){
        try{
            //更新数据库 blogger_main
            insBloggerMainDao.batchUpdateAiCategory(insBloggerCategories);
            //更新数据库 blogger
            insBloggerDao.batchUpdateAiCategory(insBloggerCategories);
        }catch (Exception e){
            log.error("update ins Analysis Category error, msg:{} ",e.getMessage());
        }
    }

    /**
     *
     * @param captionsTags
     * @return
     */
    public List<List<String>> getMediaTag(List<InsRelMediaCaptionTag> captionsTags){
        List<List<String>> mediaTags = new ArrayList<>(10);
        List<String> mediaTag = new ArrayList<>(4);
        String shortcode = "";
        for(InsRelMediaCaptionTag insRelMediaCaptionTag : captionsTags){
            if(!"".equals(shortcode) && !shortcode.equals(insRelMediaCaptionTag.getShortcode())){
                mediaTags.add(mediaTag);
                mediaTag = new ArrayList<>(4);
            }
            shortcode = insRelMediaCaptionTag.getShortcode();
            mediaTag.add(insRelMediaCaptionTag.getCaptionTag());
        }
        mediaTags.add(mediaTag);
        return mediaTags;
    }
}
